#include "app.h"
#include "hx71x.h"
#include "beep.h"
#include "lcd1602.h"
#include "wifi.h"
#include "uart.h"
#include "keyboard.h"
#include "vcom.h"
#include "utils.h"
#include "filter.h"
#include "led.h"

#include "debug.h"

#define OVER_WEIGHT_KG 3.000
#define OVER_WEIGHT_LBS 3.000 * 2.2

ulong calibration_value = 0;
uchar unit = HX71X_UNIT_KG;
ulong value;
float weight, weight_kg; 
uchar len;
uchar idata weight_str[10];
bit live = 0;

// unit switch subfunction
uchar unit_str_add(uchar * weight_str, uchar len, uchar unit)
{
    if(unit == HX71X_UNIT_LBS)
    {
        user_strcat(weight_str, len, "lbs");
        return len + 3;
    }
    else if(unit == HX71X_UNIT_KG)
    {
        user_strcat(weight_str, len, "kg");
        return len + 2;
    }
    return 0;
}

uchar overweight_str_add(uchar * weight_str, uchar len, uchar unit)
{
    if(unit == HX71X_UNIT_LBS)
    {
        if(weight > OVER_WEIGHT_LBS)
            user_strcat(weight_str, len, ";n");
        else
            user_strcat(weight_str, len, ";y");
    }
    else if(unit == HX71X_UNIT_KG)
    {
        if(weight > OVER_WEIGHT_KG)
            user_strcat(weight_str, len, ";n");
        else
            user_strcat(weight_str, len, ";y");
    }
    return len + 2;
}
// get weight subfunction
void get_weight(void)
{
    // value = hx71x_read();
    value = digital_averaging_filter(hx71x_read);
    /* 当读取的值比去皮值还要小时， 视为正常的漂移， 以去皮值为值 */
    if(value < calibration_value)
        value = 0;
    else
        value = value - calibration_value;

    weight = hx71x_get_weight(value, unit);
    len = float2char(weight, weight_str, 3);
    len = unit_str_add(weight_str, len, unit);
    lcd1602_part_clear(1,0, 16);
    lcd1602_show(1,0, weight_str); // show weight 
}

// calibrate subfunction
void calibrate_hx71x(void)
{
    calibration_value = digital_averaging_filter(hx71x_read);
    weight = 0;
    len = float2char(weight, weight_str, 3);
    unit_str_add(weight_str, len, unit);
    lcd1602_part_clear(1,0, 16);
    lcd1602_show(1,0, weight_str); // show weight 
}

void unit_switch(void)
{
    // 1kg = 2.2 LB
    if(unit == HX71X_UNIT_KG)
        unit = HX71X_UNIT_LBS;
    else if(unit == HX71X_UNIT_LBS)
        unit = HX71X_UNIT_KG;
    get_weight();
}

void app_init(void)
{
    beep_init();
    wifi_init();
    led_init();    
    lcd1602_init();
    lcd1602_show(0,0, "Wireless-E-scale");
    calibrate_hx71x();
}

void app_keyboard(void)
{
    uchar keycode;
    if(iskeyinput()) // wait for key press    
    {
        delay(500); //   
        if(iskeyinput()) // exactly key pressed    
        {    
            keycode = key_identify();    
            wait_key_release();    
            led_toggle(1);
            debug("Key is pressed\r\n\r\n");
            switch(keycode)
            {
                case 0:
                    debug("Key 1 is Pressed\r\n");
                    debug("称重\r\n\r\n");                    
                    get_weight();
                    break;
                case 1:
                    debug("Key 2 is Pressed\r\n");
                    debug("去皮\r\n\r\n");   
                    calibrate_hx71x();
                    break;
                case 2:
                    debug("Key 3 is Pressed\r\n");
                    debug("单位切换\r\n\r\n");   
                    unit_switch();
                    break;
                case 3:
                    debug("Key 4 is Pressed\r\n");
                    debug("时时显示切换\r\n\r\n");
                    live = !live;
                    break;
            }
        }
    }

}

void app_wifi(void)
{
    if(wifi_rx_ok)
    {
        debug("Wifi Get Message:\r\n");
        debug(wifi_rx_buff);
        debug("\r\n\r\n");

        led_toggle(2);
        switch(wifi_rx_buff[0]) // check first letter
        {
            case 'W': // 称重
                debug("Wifi Get W Command:\r\n称重\r\n\r\n");
                get_weight();
                overweight_str_add(weight_str, len, unit);
                wifi_send(weight_str);
                break;
            case 'C': // 去皮
                debug("Wifi Get C Command:\r\n去皮\r\n\r\n");
                calibrate_hx71x();
                break;
            case 'S': // 单位切换
                debug("Wifi Get S Command:\r\n单位切换\r\n\r\n");
                unit_switch();
                overweight_str_add(weight_str, len, unit);
                wifi_send(weight_str);
                break;
        }
        wifi_rx_ok = 0;
        wifi_rx_count = 0;
    }

}

void app_show(void)
{
    if(live)
    {
        delay(20500);
        get_weight();
        value = digital_averaging_filter(hx71x_read);
        #ifdef DEBUG
        num2char(value, debug_str);
        debug(debug_str);
        debug("\r\n");
        #endif
    }
}

void app_alarm(void)
{
    static bit over_weight_flag = 0; // 
    // value = hx71x_read();
    // /* 当读取的值比去皮值还要小时， 视为正常的漂移， 以去皮值为值 */
    // if(value < calibration_value)
    //     value = 0;
    // else
    //     value = value - calibration_value;

    // weight = hx71x_get_weight(value, HX71X_UNIT_KG);
    
    if(((unit == HX71X_UNIT_KG && weight > OVER_WEIGHT_KG) || (unit == HX71X_UNIT_LBS && weight > OVER_WEIGHT_LBS) )&& !over_weight_flag)
    {
        beep_start();
        lcd1602_part_clear(1,0, 16);
        lcd1602_show(1,0, "OverWeight!!!");
        over_weight_flag = 1;
    }
    
    if(over_weight_flag == 1)
    {
        value = digital_averaging_filter(hx71x_read);
        /* 当读取的值比去皮值还要小时， 视为正常的漂移， 以去皮值为值 */
        if(value < calibration_value)
            value = 0;
        else
            value = value - calibration_value;

        if(hx71x_get_weight(value, HX71X_UNIT_KG) < OVER_WEIGHT_KG)
        {
            beep_stop();
            lcd1602_part_clear(1,0, 16);
            lcd1602_show(1,0, "Thanks, I'm OK");
            over_weight_flag = 0;
            weight = 0;
        }
    }
}




